Skip to content

feat: ap.visual-editor.background-controls filter (#649) - #652

Merged
ViewFromTheBox merged 3 commits into
release/1.xfrom
feature/649-background-controls-filter
Jul 13, 2026
Merged

ViewFromTheBox merged 3 commits into
release/1.xfrom
feature/649-background-controls-filter

Conversation

@ViewFromTheBox

@ViewFromTheBox ViewFromTheBox commented Jul 13, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Adds ap.visual-editor.background-controls — a JS filter that lets external packages contribute panels to any block that opts into a background support, without each package enumerating target blocks and wrapping editor.BlockEdit itself.
  • Ships a single built-in editor.BlockEdit HOC that gates on supports.background / supports.color.background, then renders filter-registered controls sorted by priority (default 10, lower first) and deduped by id (last-wins).
  • Documents the filter in docs/Hooks-and-Events.md alongside the other JS-side filters (document-panels, canvas-styles, rendered-block).

Downstream artisanpack-ui/liquid-glass (and any future "effect" package) can now drop its per-package editor.BlockEdit HOC and register a single filter callback instead.

Closes #649.

API

type BackgroundControl = {
    id: string           // stable, namespaced
    label: string        // panel heading (already translated)
    priority?: number    // default 10, lower first
    render: () => ReactNode
}

type BackgroundControlContext = {
    attributes: Record<string, unknown>
    setAttributes: (attrs: Record<string, unknown>) => void
    clientId: string
    blockName: string
    blockSupports: Record<string, unknown>
}

applyFilters('ap.visual-editor.background-controls', controls, context)

Test plan

  • vitest run resources/js/visual-editor/background-controls — 20/20 pass (filter shape + HOC gating + priority ordering + block support detection)
  • Full editor suite (vitest run resources/js/visual-editor) still green apart from the pre-existing site-editor-app.test.tsx failures (verified reproducing on release/1.x with my changes stashed)
  • Manual smoke: open the dev app, select artisanpack/group, register a stub filter callback in the browser console, confirm a new PanelBody appears in the inspector; select artisanpack/separator (or any non-background block), confirm no panel appears
  • Refactor liquid-glass/resources/js/index.ts to consume the filter (follow-up PR in that repo)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added JavaScript filter support for extending visual editor background controls.
    • Blocks with background support can now display contributed appearance controls in the inspector.
    • Controls support configurable ordering, duplicate handling, and contextual block data.
  • Documentation
    • Documented JavaScript filters, available extension points, contribution formats, and registration requirements.
  • Tests
    • Added coverage for filtering, ordering, validation, rendering, and background-support behavior.

Adds a shared JS filter that lets external packages contribute panels
to the background/appearance area of any block that opts into a
background support, without each package enumerating target blocks and
wrapping editor.BlockEdit itself.

The visual editor now owns the target-block decision via a single
editor.BlockEdit HOC that gates on supports.background and
supports.color.background, then renders filter-registered controls
sorted by priority (default 10, lower first) and deduped by id
(last-wins).

Downstream packages like liquid-glass can drop their per-package
withBlockEdit HOC and register a single filter callback instead.

Closes #649
@coderabbitai

coderabbitai Bot commented Jul 13, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ViewFromTheBox, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 32 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b3625e35-2f04-4889-841c-2bfff1048f79

📥 Commits

Reviewing files that changed from the base of the PR and between 7c487a4 and 6829b54.

📒 Files selected for processing (8)
  • docs/Hooks-and-Events.md
  • resources/js/visual-editor/background-controls/__tests__/background-controls.test.ts
  • resources/js/visual-editor/background-controls/__tests__/with-background-controls.test.tsx
  • resources/js/visual-editor/background-controls/background-controls.ts
  • resources/js/visual-editor/background-controls/with-background-controls.tsx
  • resources/js/visual-editor/editor/editor-app.tsx
  • resources/js/visual-editor/site-editor/__tests__/site-editor-app.test.tsx
  • resources/js/visual-editor/site-editor/site-editor-app.tsx
📝 Walkthrough

Walkthrough

Adds the ap.visual-editor.background-controls JavaScript filter, integrates contributed controls into supported block inspectors, adds runtime validation and ordering, wires editor registration, expands tests, and documents four JavaScript filter namespaces.

Changes

Background Controls Extension

Layer / File(s) Summary
Filter contract and normalization
resources/js/visual-editor/background-controls/background-controls.ts, resources/js/visual-editor/background-controls/index.ts
Defines the filter API, control/context types, validation, priority sorting, stable ordering, and last-wins deduplication.
Block inspector integration
resources/js/visual-editor/background-controls/with-background-controls.tsx, resources/js/visual-editor/editor/editor-app.tsx
Adds support gating, renders contributed controls in InspectorControls, registers the HOC once, and wires it into editor bootstrap.
Behavior validation and hook documentation
resources/js/visual-editor/background-controls/__tests__/*, docs/Hooks-and-Events.md
Tests filtering and rendering behavior, and documents JavaScript filter contracts and execution rules.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ExternalPackage
  participant WordpressHooks
  participant BackgroundControlsHOC
  participant BlockInspector
  ExternalPackage->>WordpressHooks: Register background-control filter
  BlockInspector->>BackgroundControlsHOC: Render supported block edit
  BackgroundControlsHOC->>WordpressHooks: Apply filter with block context
  WordpressHooks-->>BackgroundControlsHOC: Return filtered controls
  BackgroundControlsHOC-->>BlockInspector: Render ordered control panels
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title names the new background-controls filter and matches the main change.
Linked Issues check ✅ Passed The PR adds the requested filter, context fields, ordering, docs, and tests for supported blocks.
Out of Scope Changes check ✅ Passed The changes are focused on the requested filter, related editor wiring, docs, and tests.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/649-background-controls-filter

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@resources/js/visual-editor/background-controls/background-controls.ts`:
- Around line 90-137: Update isBackgroundControl to validate priority when it is
present, allowing undefined but requiring a finite numeric value; reject
malformed controls before getFilteredBackgroundControls sorts them, so the
priorityA - priorityB comparator never receives invalid values.

In `@resources/js/visual-editor/background-controls/with-background-controls.tsx`:
- Around line 64-78: Update resolveBlockSupports to return a deep copy of the
validated blockType.supports object rather than the registry’s live reference,
preserving the existing empty-object behavior for missing or invalid supports.
Also add a “Treat as read-only” note to the blockSupports field in
BackgroundControlContext.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 718184b1-5935-4b97-bb11-cecea01e096b

📥 Commits

Reviewing files that changed from the base of the PR and between a192a14 and 7c487a4.

📒 Files selected for processing (7)
  • docs/Hooks-and-Events.md
  • resources/js/visual-editor/background-controls/__tests__/background-controls.test.ts
  • resources/js/visual-editor/background-controls/__tests__/with-background-controls.test.tsx
  • resources/js/visual-editor/background-controls/background-controls.ts
  • resources/js/visual-editor/background-controls/index.ts
  • resources/js/visual-editor/background-controls/with-background-controls.tsx
  • resources/js/visual-editor/editor/editor-app.tsx

- Register the BlockEdit HOC BEFORE responsive/state HOCs so it wraps
  innermost. context.attributes is now the breakpoint-merged /
  state-resolved view (not raw idle) and context.setAttributes routes
  writes through the responsive/state wrappers.
- Wire registerBackgroundControls into the site-editor bootstrap so
  the filter fires when editing templates, template parts, and
  patterns (previously dead in the site editor).
- Dedupe by id BEFORE priority sort so "last-wins mirroring
  @wordpress/hooks" tracks registration order, not sort order — a
  later addFilter overrides an earlier one at the same id regardless
  of relative priorities.
- Deep-clone context.blockSupports (structuredClone) so a filter
  callback can't corrupt @wordpress/blocks' registry via mutation.
  Freeze context.attributes and type both fields as Readonly<>.
- Wrap applyFilters in try/catch; log to console.error and return an
  empty list on throw so one bad third-party filter can't trip
  BlockCrashBoundary for every block in the session.
- Reject controls with a non-finite priority (NaN, strings, Infinity)
  at validation time — engine-dependent sort order eliminated.
- Reject empty-string id at validation time.
- Always return the Fragment shape from the HOC — a 0→1 controls
  transition no longer remounts BlockEdit and lose RichText cursor /
  drag / child hook state.
- Drop the dead `data-background-control` wrapper div.
- Move `ap.visual-editor.rendered-block` docs to the PHP filters
  section with correct description (it's a server-side PHP filter,
  not a save-time JS filter).
- Fix the docs example gate to check both `blockSupports.background`
  and `blockSupports.color.background` — the naive `!blockSupports.background`
  check would silently no-op on color-background blocks.

Overlaps with CodeRabbit review comments on PR #652 (priority
type-check + resolveBlockSupports live-reference leak).

New tests cover: registration-order-over-priority dedupe (both
directions), NaN/string/Infinity priority rejection, empty-id
rejection, thrown-callback swallowing, attributes-freeze semantics,
blockSupports deep-clone semantics, always-Fragment BlockEdit
stability across empty→non-empty controls transitions.

Test count: 20 → 27 in background-controls; full editor suite 1861 →
1868 passing (site-editor-app.test.tsx pre-existing failure remains,
now surfacing as a transitive `@wordpress/blocks` JSON-import error
during collection rather than the previous 17 runtime failures — the
file has not passed on release/1.x for this reason).

Refs #649
@ViewFromTheBox ViewFromTheBox moved this from Backlog to In Review in ArtisanPack UI Overview Jul 13, 2026
@ViewFromTheBox
ViewFromTheBox marked this pull request as ready for review July 13, 2026 22:49
The new site-editor bootstrap import of `registerBackgroundControls`
pulls the background-controls barrel into the site-editor-app test's
module graph, which transitively loads `@wordpress/block-editor` and
its `block-compare` → `diff` subpath — the same unresolved-under-jsdom
chain the file already stubs `BlockEditorBoundary` and
`BlockLibrarySidebar` for.

Stub `../../background-controls` to a no-op registrar so the shell
test can boot again on CI. The HOC and filter helpers have their own
focused suites under `background-controls/__tests__/`.

Refs #649
@ViewFromTheBox
ViewFromTheBox merged commit 2579758 into release/1.x Jul 13, 2026
6 checks passed
@github-project-automation github-project-automation Bot moved this from In Review to Done in ArtisanPack UI Overview Jul 13, 2026
@ViewFromTheBox
ViewFromTheBox deleted the feature/649-background-controls-filter branch July 13, 2026 22:57
@ViewFromTheBox ViewFromTheBox mentioned this pull request Jul 17, 2026
11 of 23 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

1 participant